<?php

namespace app\middleware;

use app\service\JwtService;
use Closure;
use think\facade\Log;
use think\Request;
use think\Response;

/**
 * 兼容版本的JWT认证中间件
 */
class JwtAuthMiddleware
{
    /**
     * 处理请求
     *
     * @param Request $request
     * @param Closure $next
     * @return Response
     */
    public function handle(Request $request, Closure $next): Response
    {
        try {
            // 1. 提取Token
            $token = $this->extractToken($request);
            
            // 2. 验证Token格式
            if (empty($token)) {
                return json([
                    'code' => 3001,
                    'message' => '缺少认证令牌',
                    'result' => [],
                    'timestamp' => time(),
                ])->code(401);
            }

            // 3. 验证Token有效性
            if (!JwtService::validateToken($token)) {
                return json([
                    'code' => 3002,
                    'message' => '认证令牌无效',
                    'result' => [],
                    'timestamp' => time(),
                ])->code(401);
            }

            // 4. 解析Token获取用户信息
            $decoded = JwtService::parseToken($token);
            $userInfo = $decoded->user ?? null;

            if (empty($userInfo)) {
                return json([
                    'code' => 3002,
                    'message' => '认证令牌无效',
                    'result' => [],
                    'timestamp' => time(),
                ])->code(401);
            }

            // 5. 将用户信息存储到请求中
            $request->userInfo = (object)$userInfo;
            $request->token = $token;

            // 6. 记录访问日志 - 修复类型转换问题
            $this->logAccess($request, (array)$userInfo);

            return $next($request);

        } catch (\Exception $e) {
            logs('JWT中间件异常: ' . $e->getMessage(), [
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'url' => $request->url(true),
                'trace' => $e->getTraceAsString(),
            ],'error');
            
            return json([
                'code' => 3000,
                'message' => '认证失败',
                'result' => [],
                'timestamp' => time(),
            ])->code(401);
        }
    }

    /**
     * 提取Token
     */
    private function extractToken(Request $request): string
    {
        // 1. 从Authorization头获取
        $authHeader = $request->header('Authorization', '');
        if (strpos($authHeader, 'Bearer ') === 0) {
            return substr($authHeader, 7);
        }

        // 2. 从请求参数获取
        $token = $request->param('token', '');
        if (!empty($token)) {
            return $token;
        }

        // 3. 从Cookie获取
        return $request->cookie('access_token', '');
    }

    /**
     * 记录访问日志
     */
    private function logAccess(Request $request, array $userInfo): void
    {
        try {
            // 使用新的日志服务
            \app\service\LogService::apiAccess('API访问记录', [
                'user_id' => $userInfo['id'] ?? 0,
                'openid' => $userInfo['openid'] ?? '',
                'method' => $request->method(),
                'url' => $request->url(true),
                'ip' => $request->ip(),
                'user_agent' => $request->header('User-Agent'),
            ]);

        } catch (\Exception $e) {
            // 日志记录失败不应该影响主流程
            Log::warning('访问日志记录失败: ' . $e->getMessage());
        }
    }

    /**
     * 用户登出（静态方法，供外部调用）
     */
    public static function logout(string $token): void
    {
        try {
            // 简化版本，仅记录日志
            logs('用户登出', ['token' => substr($token, 0, 10) . '...']);
        } catch (\Exception $e) {
            Log::warning('登出日志记录失败: ' . $e->getMessage());
        }
    }

    /**
     * 获取用户在线状态（静态方法，供外部调用）
     */
    public static function getUserOnlineStatus(int $userId): ?array
    {
        // 简化版本，返回null
        return null;
    }
}
